{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can use `enumerate` to loop through an iterable while keeping track of the index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "items = [\"apple\", \"banana\", \"cherry\"]\n",
    "for index, item in enumerate(items, start=1):\n",
    "    print(f\"{index}: {item}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then there’s zip, which combines two or more iterables element-wise, creating tuples:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "names = [\"Alice\", \"Bob\", \"Charlie\"]\n",
    "scores = [85, 90, 95]\n",
    "for name, score in zip(names, scores):\n",
    "    print(f\"{name}: {score}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`any` and `all` are also quite useful:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "numbers = [1, 0, 3, 0]\n",
    "print(any(numbers))  # Output: True (at least one non-zero)\n",
    "print(all(numbers))  # Output: False (not all are non-zero)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`map` transforms an iterable by applying a function to each element:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 4, 9, 16]\n"
     ]
    }
   ],
   "source": [
    "numbers = [1, 2, 3, 4]\n",
    "squares = map(lambda x: x**2, numbers)\n",
    "print(list(squares))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Use `filter` to select elements based on a condition:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "numbers = [10, 15, 20, 25, 30]\n",
    "divisible_by_10 = filter(lambda x: x % 10 == 0, numbers)\n",
    "print(list(divisible_by_10))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Use `reversed` to reverse an iterable without modifying it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "cherry\n",
      "banana\n",
      "apple\n"
     ]
    }
   ],
   "source": [
    "items = [\"apple\", \"banana\", \"cherry\"]\n",
    "for item in reversed(items):\n",
    "    print(item)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Did you know `min` and `max` also work with custom keys?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The longest word is banana with 6 characters.\n"
     ]
    }
   ],
   "source": [
    "words = [\"apple\", \"banana\", \"cherry\"]\n",
    "longest_word = max(words, key=len)\n",
    "print(f\"The longest word is {longest_word} with {len(longest_word)} characters.\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
